import os
import re
import tkinter as tk
from tkinter import filedialog, ttk, messagebox
from pathlib import Path

# 添加自然排序函数
def natural_sort_key(s):
    """用于自然排序的键函数，使数字按照数值大小排序"""
    return [int(text) if text.isdigit() else text.lower()
            for text in re.split(r'(\d+)', s)]

class FileRenamerApp:
    def __init__(self, root):
        self.root = root
        self.root.title("文件批量重命名工具")
        self.root.geometry("680x620")
        
        # 当前选择的文件夹路径
        self.current_path = tk.StringVar()
        
        # 存储各级文件夹名称
        self.level_folders = {}
        
        # 最大文件夹层级
        self.max_detected_level = 0
        
        # 创建界面组件
        self.create_widgets()
        
    def create_widgets(self):
        # 顶部工具栏
        toolbar_frame = ttk.Frame(self.root)
        toolbar_frame.pack(fill=tk.X, padx=10, pady=10)
        
        ttk.Button(toolbar_frame, text="选择文件夹", command=self.select_folder).pack(side=tk.LEFT, padx=5)
        ttk.Entry(toolbar_frame, textvariable=self.current_path, width=50).pack(side=tk.LEFT, padx=5)
        ttk.Button(toolbar_frame, text="刷新", command=self.refresh_folder).pack(side=tk.LEFT, padx=5)
        ttk.Button(toolbar_frame, text="帮助", command=self.show_help).pack(side=tk.LEFT, padx=5)
        
        # 主内容区域
        content_frame = ttk.Frame(self.root)
        content_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        # 左侧文件树
        tree_frame = ttk.LabelFrame(content_frame, text="文件夹结构")
        tree_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5, pady=5)
        
        # 创建带滚动条的树控件 - 修复布局管理器冲突
        tree_container = ttk.Frame(tree_frame)
        tree_container.pack(fill=tk.BOTH, expand=True)
        
        # 创建树控件和滚动条
        self.tree = ttk.Treeview(tree_container)
        tree_scroll_y = ttk.Scrollbar(tree_container, orient=tk.VERTICAL, command=self.tree.yview)
        tree_scroll_x = ttk.Scrollbar(tree_container, orient=tk.HORIZONTAL, command=self.tree.xview)
        
        # 配置树控件的滚动
        self.tree.configure(yscrollcommand=tree_scroll_y.set, xscrollcommand=tree_scroll_x.set)
        
        # 使用grid布局管理器
        self.tree.grid(row=0, column=0, sticky="nsew")
        tree_scroll_y.grid(row=0, column=1, sticky="ns")
        tree_scroll_x.grid(row=1, column=0, sticky="ew")
        
        # 配置网格权重
        tree_container.grid_rowconfigure(0, weight=1)
        tree_container.grid_columnconfigure(0, weight=1)

        # 右侧重命名规则设置
        rename_frame = ttk.LabelFrame(content_frame, text="重命名规则设置")
        rename_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=5, pady=5)
        
        # 重命名级别选择
        self.level_frame = ttk.Frame(rename_frame)
        self.level_frame.pack(fill=tk.X, padx=5, pady=5)
        
        ttk.Label(self.level_frame, text="选择重命名级别：").pack(anchor=tk.W)
        
        # 创建一个框架来容纳动态生成的单选按钮
        self.radio_frame = ttk.Frame(self.level_frame)
        self.radio_frame.pack(fill=tk.X, padx=5, pady=5)
        
        # 初始化级别变量
        self.level_var = tk.IntVar(value=1)
        self.level_var.trace_add("write", self.update_level_info)
        
        # 提示标签 - 初始状态
        self.level_prompt = ttk.Label(self.level_frame, text="请先选择文件夹以显示可用级别")
        self.level_prompt.pack(anchor=tk.W, padx=5, pady=5)
        
        # 添加显示当前级别文件夹的标签
        self.level_info_var = tk.StringVar(value="")
        self.level_info_label = ttk.Label(rename_frame, textvariable=self.level_info_var, font=("Arial", 10, "italic"))
        self.level_info_label.pack(anchor=tk.W, padx=5, pady=5)
        
        # 文件名匹配模式
        ttk.Label(rename_frame, text="文件名匹配模式：").pack(anchor=tk.W, padx=5, pady=5)
        self.pattern_var = tk.StringVar(value="*")
        ttk.Entry(rename_frame, textvariable=self.pattern_var).pack(fill=tk.X, padx=5, pady=5)
        
        # 新文件名格式
        ttk.Label(rename_frame, text="新文件名格式：").pack(anchor=tk.W, padx=5, pady=5)
        self.format_var = tk.StringVar(value="{原文件名}")
        ttk.Entry(rename_frame, textvariable=self.format_var).pack(fill=tk.X, padx=5, pady=5)
        

        
        
        
        # 预览区域
        ttk.Label(rename_frame, text="重命名预览：").pack(anchor=tk.W, padx=5, pady=5)
        self.preview_text = tk.Text(rename_frame, height=10)
        self.preview_text.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
        
        # 操作按钮
        button_frame = ttk.Frame(rename_frame)
        button_frame.pack(fill=tk.X, padx=5, pady=10)
        
        ttk.Button(button_frame, text="生成预览", command=self.generate_preview).pack(side=tk.LEFT, padx=5)
        ttk.Button(button_frame, text="执行重命名", command=self.execute_rename).pack(side=tk.LEFT, padx=5)
        
        # 状态栏
        self.status_var = tk.StringVar(value="状态：准备就绪")
        ttk.Label(self.root, textvariable=self.status_var, relief=tk.SUNKEN, anchor=tk.W).pack(fill=tk.X, padx=10, pady=5)
    
    def update_level_radio_buttons(self):
        """根据检测到的文件夹层级更新单选按钮"""
        # 清除现有的单选按钮
        for widget in self.radio_frame.winfo_children():
            widget.destroy()
        
        # 隐藏提示标签
        self.level_prompt.pack_forget()
        
        # 如果没有检测到文件夹，显示提示
        if self.max_detected_level == 0:
            self.level_prompt.pack(anchor=tk.W, padx=5, pady=5)
            return
        
        # 根据检测到的最大层级创建单选按钮
        for i in range(1, self.max_detected_level + 1):
            # 为文件级别添加特殊标记
            if i in self.level_folders:
                # 检查这个级别是否只包含文件级别的文件夹
                is_file_level = all(i > 1 and path in self.level_folders.get(i-1, []) for path in self.level_folders[i])
                
                if is_file_level:
                    ttk.Radiobutton(self.radio_frame, text=f"第{i}级(文件)", variable=self.level_var, value=i).pack(side=tk.LEFT, padx=5)
                else:
                    ttk.Radiobutton(self.radio_frame, text=f"第{i}级", variable=self.level_var, value=i).pack(side=tk.LEFT, padx=5)
        
        # 默认选择第一级
        self.level_var.set(1)
    
    def update_level_info(self, *args):
        """更新当前选择级别的文件夹信息"""
        level = self.level_var.get()
        if level in self.level_folders:
            folders = self.level_folders[level]
            if folders:
                # 检查是否是文件级别
                is_file_level = all(level > 1 and path in self.level_folders.get(level-1, []) for path in folders)
                
                if is_file_level:
                    folder_names = ", ".join([os.path.basename(f) for f in folders])
                    self.level_info_var.set(f"第{level}级(文件级别): {folder_names}")
                else:
                    folder_names = ", ".join([os.path.basename(f) for f in folders])
                    self.level_info_var.set(f"第{level}级文件夹: {folder_names}")
            else:
                self.level_info_var.set(f"第{level}级没有文件夹")
        else:
            self.level_info_var.set("")
    
    def select_folder(self):
        folder_path = filedialog.askdirectory(title="选择要操作的文件夹")
        if folder_path:
            self.current_path.set(folder_path)
            self.refresh_folder()
    
    def refresh_folder(self):
        path = self.current_path.get()
        if not path or not os.path.isdir(path):
            messagebox.showerror("错误", "请选择有效的文件夹路径")
            return
        
        # 清空树控件
        for item in self.tree.get_children():
            self.tree.delete(item)
        
        # 重置文件夹级别信息
        self.level_folders = {}
        self.max_detected_level = 0
        
        # 添加根节点
        root_node = self.tree.insert("", "end", text=os.path.basename(path) or path, values=(path, "directory"))
        
        # 递归添加子节点，将根目录设置为第0级
        self.populate_tree(root_node, path, level=0)
        
        # 展开根节点
        self.tree.item(root_node, open=True)
        
        # 更新单选按钮
        self.update_level_radio_buttons()
        
        # 更新当前级别信息
        self.update_level_info()
        
        self.status_var.set(f"状态：已加载文件夹 {path}，检测到 {self.max_detected_level} 级目录")
    
    def populate_tree(self, parent, path, level=1, max_level=10):
        if level > max_level:
            return
        
        try:
            # 确保当前级别在字典中有一个条目
            if level not in self.level_folders:
                self.level_folders[level] = []
            
            # 将当前路径添加到对应级别的文件夹列表中
            self.level_folders[level].append(path)
            
            # 更新检测到的最大层级
            self.max_detected_level = max(self.max_detected_level, level)
            
            # 列出目录内容并按自然排序
            items = sorted(os.listdir(path), key=natural_sort_key)
            
            has_subdirs = False
            has_files = False
            
            for item in items:
                item_path = os.path.join(path, item)
                is_dir = os.path.isdir(item_path)
                
                # 插入节点
                icon = "📁" if is_dir else "📄"
                node = self.tree.insert(parent, "end", text=f"{icon} {item}", values=(item_path, "directory" if is_dir else "file"))
                
                # 如果是目录，则递归添加子节点
                if is_dir:
                    has_subdirs = True
                    self.populate_tree(node, item_path, level + 1, max_level)
                else:
                    # 这是一个文件，将其父目录添加到下一级的文件级别中
                    has_files = True
                    file_level = level + 1
                    if file_level not in self.level_folders:
                        self.level_folders[file_level] = []
                    if path not in self.level_folders[file_level]:
                        self.level_folders[file_level].append(path)
                    # 更新最大层级，考虑文件级别
                    self.max_detected_level = max(self.max_detected_level, file_level)
            
            # 如果当前目录没有子目录但有文件，确保文件级别被记录
            if not has_subdirs and has_files:
                # 已经在上面的循环中处理了文件级别
                pass
                
        except PermissionError:
            self.tree.insert(parent, "end", text="⚠️ 无权限访问", values=(path, "error"))
        except Exception as e:
            self.tree.insert(parent, "end", text=f"⚠️ 错误: {str(e)}", values=(path, "error"))

    def get_files_at_level(self, path, target_level, current_level=1, get_folders=False):
        """获取指定级别的所有文件或文件夹"""
        if not os.path.exists(path):
            return []
        
        # 如果是文件级别（比如第4级是第3级文件夹下的文件）
        if current_level + 1 == target_level:
            # 检查当前路径是否在目标级别的文件夹列表中
            if target_level in self.level_folders and path in self.level_folders[target_level]:
                # 返回当前目录下的所有文件，并按自然排序
                if os.path.isdir(path):
                    if get_folders:
                        return []
                    else:
                        files = [os.path.join(path, f) for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))]
                        return sorted(files, key=lambda x: natural_sort_key(os.path.basename(x)))
        
        # 如果是目标文件夹级别
        if current_level == target_level:
            # 如果是目标级别，根据get_folders参数返回文件或文件夹
            if os.path.isdir(path):
                if get_folders:
                    # 返回当前目录下的所有文件夹，并按自然排序
                    folders = [os.path.join(path, f) for f in os.listdir(path) if os.path.isdir(os.path.join(path, f))]
                    return sorted(folders, key=lambda x: natural_sort_key(os.path.basename(x)))
                else:
                    # 返回当前目录下的所有文件，并按自然排序
                    files = [os.path.join(path, f) for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))]
                    return sorted(files, key=lambda x: natural_sort_key(os.path.basename(x)))
            return []
        
        # 如果还没到目标级别，继续向下递归，但只递归到目标级别，不再继续
        result = []
        if os.path.isdir(path) and current_level < target_level:
            for item in sorted(os.listdir(path), key=natural_sort_key):
                item_path = os.path.join(path, item)
                if os.path.isdir(item_path):
                    result.extend(self.get_files_at_level(item_path, target_level, current_level + 1, get_folders))
        
        return result
    
    def match_files(self, files, pattern):
        """根据模式匹配文件"""
        if pattern == '*':
            return files
        
        matched_files = []
        try:
            # 尝试使用正则表达式匹配
            regex = re.compile(pattern)
            for file_path in files:
                filename = os.path.basename(file_path)
                if regex.search(filename):
                    matched_files.append(file_path)
        except re.error:
            # 如果正则表达式无效，使用通配符匹配
            pattern = pattern.replace('*', '.*').replace('?', '.')
            regex = re.compile(pattern)
            for file_path in files:
                filename = os.path.basename(file_path)
                if regex.search(filename):
                    matched_files.append(file_path)
        
        return matched_files
    
    def process_string_operations(self, text, original_name):
        """处理字符串操作"""
        try:
            # 处理切片操作
            if '[' in text and ']' in text:
                # 提取切片表达式
                slice_match = re.search(r'\[(.*?)\]', text)
                if slice_match:
                    slice_expr = slice_match.group(1)
                    # 处理切片表达式
                    if ':' in slice_expr:
                        start, end = slice_expr.split(':')
                        start = int(start) if start else 0
                        end = int(end) if end else len(original_name)
                        text = original_name[start:end]
                    else:
                        index = int(slice_expr)
                        text = original_name[index]
            
            # 处理字符串方法
            if '.' in text:
                parts = text.split('.')
                current = parts[0]
                for part in parts[1:]:
                    if '(' in part:
                        method, args = part.split('(', 1)
                        args = args.rstrip(')')
                        if method == 'lstrip':
                            current = current.lstrip(args.strip("'"))
                        elif method == 'rstrip':
                            current = current.rstrip(args.strip("'"))
                        elif method == 'strip':
                            current = current.strip(args.strip("'"))
                        elif method == 'replace':
                            old, new = args.split(',', 1)
                            current = current.replace(old.strip("'"), new.strip("'"))
                        elif method == 'upper':
                            current = current.upper()
                        elif method == 'lower':
                            current = current.lower()
                        elif method == 'capitalize':
                            current = current.capitalize()
                        elif method == 'title':
                            current = current.title()
                        elif method == 'split':
                            # 处理split操作
                            delimiter = args.strip("'")
                            parts = current.split(delimiter)
                            # 检查是否有索引操作
                            if '[' in part:
                                index_match = re.search(r'\[(\d+)\]', part)
                                if index_match:
                                    index = int(index_match.group(1))
                                    if 0 <= index < len(parts):
                                        current = parts[index]
                                    else:
                                        current = ""
                            else:
                                current = parts
                        elif method == 'zfill':
                            # 处理zfill操作
                            try:
                                width = int(args)
                                # 确保current是字符串
                                if not isinstance(current, str):
                                    current = str(current)
                                # 如果是数字字符串，先去掉前导零
                                if current.isdigit():
                                    current = str(int(current))
                                # 使用zfill填充
                                current = current.zfill(width)
                            except ValueError:
                                current = current
                    else:
                        if part == 'upper':
                            current = current.upper()
                        elif part == 'lower':
                            current = current.lower()
                        elif part == 'capitalize':
                            current = current.capitalize()
                        elif part == 'title':
                            current = current.title()
            
            return text
        except Exception as e:
            print(f"字符串处理错误: {str(e)}")
            return text

    def generate_preview(self):
        path = self.current_path.get()
        level = self.level_var.get()
        pattern = self.pattern_var.get()
        format_str = self.format_var.get()
        
        if not path or not os.path.isdir(path):
            messagebox.showerror("错误", "请选择有效的文件夹路径")
            return
        
        # 清空预览区域
        self.preview_text.delete(1.0, tk.END)
        
        # 检查是否是文件级别
        is_file_level = level in self.level_folders and all(level > 1 and p in self.level_folders.get(level-1, []) for p in self.level_folders[level])
        
        if is_file_level:
            # 获取指定级别的文件
            items = self.get_files_at_level(path, level)
            item_type = "文件"
        else:
            # 获取指定级别的文件夹
            items = self.get_files_at_level(path, level, get_folders=True)
            item_type = "文件夹"
        
        # 根据模式匹配项目
        matched_items = self.match_files(items, pattern)
        
        # 生成预览
        if not matched_items:
            self.preview_text.insert(tk.END, f"没有找到匹配的{item_type}")
            return
        
        # 按文件夹分组
        folder_groups = {}
        for item_path in matched_items:
            folder = os.path.dirname(item_path)
            if folder not in folder_groups:
                folder_groups[folder] = []
            folder_groups[folder].append(item_path)
        
        # 为每个文件夹单独生成预览
        for folder, items in folder_groups.items():
            counter = 1
            # 获取上级文件夹名称
            parent_folder = os.path.basename(folder)
            
            for item_path in items:
                try:
                    dir_path = os.path.dirname(item_path)
                    original_name = os.path.basename(item_path)
                    
                    # 替换序号占位符
                    current_format = format_str
                    
                    # 先处理带起始值的 {序号:NdM} 格式
                    for match in re.finditer(r"\{序号:(\d+)d(\d+)\}", current_format):
                        width = int(match.group(1))
                        start_value = int(match.group(2))
                        current_counter = counter + start_value - 1  # 调整计数器值
                        current_format = current_format.replace(match.group(0), f"{current_counter:0{width}d}")
                    
                    # 再处理标准的 {序号:Nd} 格式
                    for match in re.finditer(r"\{序号:(\d+)d\}", current_format):
                        width = int(match.group(1))
                        current_format = current_format.replace(match.group(0), f"{counter:0{width}d}")
                    
                    # 再处理简单的 {序号} 格式
                    if "{序号}" in current_format:
                        current_format = current_format.replace("{序号}", str(counter))
                    
                    # 替换上级文件夹名称
                    if "{上级文件夹}" in current_format:
                        current_format = current_format.replace("{上级文件夹}", parent_folder)
                    
                    if os.path.isfile(item_path):
                        # 文件处理：保留扩展名
                        name_without_ext, ext = os.path.splitext(original_name)
                        
                        # 处理原文件名中的高级操作
                        if "{原文件名" in current_format:
                            # 提取原文件名操作表达式
                            for match in re.finditer(r"\{原文件名(.*?)\}", current_format):
                                operation = match.group(1)
                                if not operation:  # 如果是简单的{原文件名}
                                    processed = name_without_ext
                                else:
                                    # 处理split操作
                                    if 'split' in operation:
                                        # 提取分隔符和索引
                                        split_match = re.search(r'split\([\'"]?([^\'"]*)[\'"]?\)\[(\d+)\]', operation)
                                        if split_match:
                                            delimiter = split_match.group(1)
                                            index = int(split_match.group(2))
                                            parts = name_without_ext.split(delimiter)
                                            if 0 <= index < len(parts):
                                                processed = parts[index]
                                            else:
                                                processed = ""
                                        else:
                                            processed = name_without_ext
                                    # 处理zfill操作
                                    elif 'zfill' in operation:
                                        # 提取宽度
                                        zfill_match = re.search(r'zfill\((\d+)\)', operation)
                                        if zfill_match:
                                            width = int(zfill_match.group(1))
                                            # 如果是数字字符串，先去掉前导零
                                            if name_without_ext.isdigit():
                                                processed = str(int(name_without_ext)).zfill(width)
                                            else:
                                                processed = name_without_ext.zfill(width)
                                        else:
                                            processed = name_without_ext
                                    else:
                                        processed = self.process_string_operations(operation, name_without_ext)
                                current_format = current_format.replace(match.group(0), processed)
                        
                        new_name = current_format + ext
                    else:
                        # 文件夹处理：直接替换名称
                        if "{原文件名" in current_format:
                            # 提取原文件名操作表达式
                            for match in re.finditer(r"\{原文件名(.*?)\}", current_format):
                                operation = match.group(1)
                                if not operation:  # 如果是简单的{原文件名}
                                    processed = original_name
                                else:
                                    # 处理split操作
                                    if 'split' in operation:
                                        # 提取分隔符和索引
                                        split_match = re.search(r'split\([\'"]?([^\'"]*)[\'"]?\)\[(\d+)\]', operation)
                                        if split_match:
                                            delimiter = split_match.group(1)
                                            index = int(split_match.group(2))
                                            parts = original_name.split(delimiter)
                                            if 0 <= index < len(parts):
                                                processed = parts[index]
                                            else:
                                                processed = ""
                                        else:
                                            processed = original_name
                                    # 处理zfill操作
                                    elif 'zfill' in operation:
                                        # 提取宽度
                                        zfill_match = re.search(r'zfill\((\d+)\)', operation)
                                        if zfill_match:
                                            width = int(zfill_match.group(1))
                                            # 如果是数字字符串，先去掉前导零
                                            if original_name.isdigit():
                                                processed = str(int(original_name)).zfill(width)
                                            else:
                                                processed = original_name.zfill(width)
                                        else:
                                            processed = original_name
                                    else:
                                        processed = self.process_string_operations(operation, original_name)
                                current_format = current_format.replace(match.group(0), processed)
                        
                        new_name = current_format
                    
                    self.preview_text.insert(tk.END, f"{original_name} → {new_name}\n")
                    counter += 1
                except Exception as e:
                    print(f"预览失败: {item_path} - {str(e)}")
        
        self.status_var.set(f"状态：找到 {len(matched_items)} 个匹配的{item_type}")
    
    def execute_rename(self):
        path = self.current_path.get()
        level = self.level_var.get()
        pattern = self.pattern_var.get()
        format_str = self.format_var.get()
        
        if not path or not os.path.isdir(path):
            messagebox.showerror("错误", "请选择有效的文件夹路径")
            return
        
        # 检查是否是文件级别
        is_file_level = level in self.level_folders and all(level > 1 and p in self.level_folders.get(level-1, []) for p in self.level_folders[level])
        
        if is_file_level:
            # 获取指定级别的文件
            items = self.get_files_at_level(path, level)
            item_type = "文件"
        else:
            # 获取指定级别的文件夹
            items = self.get_files_at_level(path, level, get_folders=True)
            item_type = "文件夹"
        
        # 根据模式匹配项目
        matched_items = self.match_files(items, pattern)
        
        if not matched_items:
            messagebox.showinfo("提示", f"没有找到匹配的{item_type}")
            return
        
        # 确认操作
        if not messagebox.askyesno("确认", f"确定要重命名 {len(matched_items)} 个{item_type}吗？此操作不可撤销！"):
            return
        
        # 执行重命名
        success_count = 0
        failed_count = 0
        
        # 按文件夹分组
        folder_groups = {}
        for item_path in matched_items:
            folder = os.path.dirname(item_path)
            if folder not in folder_groups:
                folder_groups[folder] = []
            folder_groups[folder].append(item_path)
        
        # 如果是文件夹，需要从深到浅排序
        if not is_file_level:
            sorted_folders = sorted(folder_groups.keys(), key=lambda x: x.count(os.sep), reverse=True)
        else:
            sorted_folders = folder_groups.keys()
        
        # 为每个文件夹单独执行重命名
        for folder in sorted_folders:
            items = folder_groups[folder]
            counter = 1
            # 获取上级文件夹名称
            parent_folder = os.path.basename(folder)
            
            for item_path in items:
                try:
                    dir_path = os.path.dirname(item_path)
                    original_name = os.path.basename(item_path)
                    
                    # 替换序号占位符
                    current_format = format_str
                    
                    # 先处理带起始值的 {序号:NdM} 格式
                    for match in re.finditer(r"\{序号:(\d+)d(\d+)\}", current_format):
                        width = int(match.group(1))
                        start_value = int(match.group(2))
                        current_counter = counter + start_value - 1  # 调整计数器值
                        current_format = current_format.replace(match.group(0), f"{current_counter:0{width}d}")
                    
                    # 再处理标准的 {序号:Nd} 格式
                    for match in re.finditer(r"\{序号:(\d+)d\}", current_format):
                        width = int(match.group(1))
                        current_format = current_format.replace(match.group(0), f"{counter:0{width}d}")
                    
                    # 再处理简单的 {序号} 格式
                    if "{序号}" in current_format:
                        current_format = current_format.replace("{序号}", str(counter))
                    
                    # 替换上级文件夹名称
                    if "{上级文件夹}" in current_format:
                        current_format = current_format.replace("{上级文件夹}", parent_folder)
                    
                    if os.path.isfile(item_path):
                        # 文件处理：保留扩展名
                        name_without_ext, ext = os.path.splitext(original_name)
                        
                        # 处理原文件名中的高级操作
                        if "{原文件名" in current_format:
                            # 提取原文件名操作表达式
                            for match in re.finditer(r"\{原文件名(.*?)\}", current_format):
                                operation = match.group(1)
                                if not operation:  # 如果是简单的{原文件名}
                                    processed = name_without_ext
                                else:
                                    # 处理split操作
                                    if 'split' in operation:
                                        # 提取分隔符和索引
                                        split_match = re.search(r'split\([\'"]?([^\'"]*)[\'"]?\)\[(\d+)\]', operation)
                                        if split_match:
                                            delimiter = split_match.group(1)
                                            index = int(split_match.group(2))
                                            parts = name_without_ext.split(delimiter)
                                            if 0 <= index < len(parts):
                                                processed = parts[index]
                                            else:
                                                processed = ""
                                        else:
                                            processed = name_without_ext
                                    # 处理zfill操作
                                    elif 'zfill' in operation:
                                        # 提取宽度
                                        zfill_match = re.search(r'zfill\((\d+)\)', operation)
                                        if zfill_match:
                                            width = int(zfill_match.group(1))
                                            # 如果是数字字符串，先去掉前导零
                                            if name_without_ext.isdigit():
                                                processed = str(int(name_without_ext)).zfill(width)
                                            else:
                                                processed = name_without_ext.zfill(width)
                                        else:
                                            processed = name_without_ext
                                    else:
                                        processed = self.process_string_operations(operation, name_without_ext)
                                current_format = current_format.replace(match.group(0), processed)
                        
                        new_name = current_format + ext
                    else:
                        # 文件夹处理：直接替换名称
                        if "{原文件名" in current_format:
                            # 提取原文件名操作表达式
                            for match in re.finditer(r"\{原文件名(.*?)\}", current_format):
                                operation = match.group(1)
                                if not operation:  # 如果是简单的{原文件名}
                                    processed = original_name
                                else:
                                    # 处理split操作
                                    if 'split' in operation:
                                        # 提取分隔符和索引
                                        split_match = re.search(r'split\([\'"]?([^\'"]*)[\'"]?\)\[(\d+)\]', operation)
                                        if split_match:
                                            delimiter = split_match.group(1)
                                            index = int(split_match.group(2))
                                            parts = original_name.split(delimiter)
                                            if 0 <= index < len(parts):
                                                processed = parts[index]
                                            else:
                                                processed = ""
                                        else:
                                            processed = original_name
                                    # 处理zfill操作
                                    elif 'zfill' in operation:
                                        # 提取宽度
                                        zfill_match = re.search(r'zfill\((\d+)\)', operation)
                                        if zfill_match:
                                            width = int(zfill_match.group(1))
                                            # 如果是数字字符串，先去掉前导零
                                            if original_name.isdigit():
                                                processed = str(int(original_name)).zfill(width)
                                            else:
                                                processed = original_name.zfill(width)
                                        else:
                                            processed = original_name
                                    else:
                                        processed = self.process_string_operations(operation, original_name)
                                current_format = current_format.replace(match.group(0), processed)
                        
                        new_name = current_format
                    
                    new_path = os.path.join(dir_path, new_name)
                    
                    # 执行重命名
                    os.rename(item_path, new_path)
                    success_count += 1
                    counter += 1
                except Exception as e:
                    print(f"重命名失败: {item_path} - {str(e)}")
                    failed_count += 1
                    messagebox.showerror("错误", f"重命名失败: {item_path}\n错误信息: {str(e)}")
        
        messagebox.showinfo("完成", f"重命名操作已完成！\n\n成功: {success_count} 个{item_type}\n失败: {failed_count} 个{item_type}")
        self.status_var.set(f"状态：重命名完成 | 成功: {success_count}, 失败: {failed_count}")
        
        # 刷新文件夹
        self.refresh_folder()
    
    def show_help(self):
        help_window = tk.Toplevel(self.root)
        help_window.title("帮助")
        help_window.geometry("800x600")
        
        # 创建文本框和滚动条
        text_frame = ttk.Frame(help_window)
        text_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        scrollbar = ttk.Scrollbar(text_frame)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        
        help_text = tk.Text(text_frame, wrap=tk.WORD, yscrollcommand=scrollbar.set)
        help_text.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.config(command=help_text.yview)
        
        # 设置文本内容
        help_content = """
        文件批量重命名工具使用帮助：

        一、文件名匹配模式
        支持以下格式：
        * * - 匹配所有文件
        * *.txt - 匹配所有txt文件
        * test* - 匹配以test开头的文件
        * *test* - 匹配包含test的文件
        * test?.txt - 匹配test1.txt, test2.txt等
        * [0-9]* - 匹配以数字开头的文件
        * [a-z]* - 匹配以小写字母开头的文件
        * [A-Z]* - 匹配以大写字母开头的文件
        * [abc]* - 匹配以a、b或c开头的文件
        * test[0-9]{3}.txt - 匹配test001.txt到test999.txt
        * (test|demo)* - 匹配以test或demo开头的文件

        二、新文件名格式
        1. 基本占位符：
           * {原文件名} - 原始文件名（不含扩展名）
           * {序号} - 从1开始的序号
           * {序号:Nd} - 指定N位数的序号,不足补0
             例如：{序号:3d}生成001, 002...
           * {序号:NdM} - 指定N位数的序号,从M开始
             例如：{序号:3d5}生成005, 006...
           * {上级文件夹} - 当前文件所在的上级文件夹名称

        2. 文件名切片：
           * {原文件名[开始:结束]} - 从原文件名中提取指定范围的字符
             例如：
             - {原文件名[0:3]} 提取前3个字符
             - {原文件名[3:]} 提取从第4个字符到末尾
             - {原文件名[:3]} 提取前3个字符
             - {原文件名[-3:]} 提取最后3个字符

        三、实际应用示例
        1. 处理分隔符：
           - {原文件名.split('-')[0]} 获取第一个横线前的部分

        2. 复杂示例：
           原文件名：XX000147-WS•2002-C-001-0001-005.jpg
           - {原文件名[0:8]} 提取 "XX000147"
           - {原文件名[9:13]} 提取 "WS•2"
           - {原文件名[14:17]} 提取 "002"
           - {原文件名[22:26].lstrip('0')} 将 "0001" 变成 "1"
           - {原文件名[22:26].lstrip('0').zfill(3)} 将 "0001" 变成 "001"

        注意事项：
        1. 重命名操作不可撤销，请先使用预览功能确认效果
        2. 建议在重要文件操作前先备份
        3. 如果遇到权限问题，请确保有足够的文件操作权限

        如有问题请联系：327936559@qq.com
        """
        
        help_text.insert(tk.END, help_content)
        help_text.config(state=tk.DISABLED)  # 设置为只读
        
        # 添加关闭按钮
        close_button = ttk.Button(help_window, text="关闭", command=help_window.destroy)
        close_button.pack(pady=10)

# 创建并运行应用
if __name__ == "__main__":
    root = tk.Tk()
    app = FileRenamerApp(root)
    root.mainloop()

